package pers.vic.boot.security.data.interceptor;

import java.sql.Connection;
import java.util.Properties;
import java.util.Set;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import pers.vic.boot.security.data.enums.RowDataHandlerType;
import pers.vic.boot.security.data.model.DataRowAuthColumn;
import pers.vic.boot.security.data.model.DataRowAuthModel;



/**
 * @description: 权限拦截器 ,  拦截StatementHandler对象的prepare ,然后重写SQL 加入where条件过滤;
 * 	使用方式: RowDataHelper.start
 * @author: Vic.xu
 * @date: 2020年2月11日 下午1:41:39
 */
@Intercepts({
		@Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class, Integer.class }) })
public class RowDataHelper extends AuthorityMethod implements Interceptor {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(RowDataHelper.class);

	/**
	 * 1、获取到拦截到的StatementHandler对象； 2、封装StatementHandler对象；
	 * 3、执行Invocation对应的数据库操作方法；
	 */
	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		StatementHandler target = (StatementHandler) invocation.getTarget();
		handler(target);
		return invocation.proceed();
	}

	/**
	 * 返回目标对象的代理对象
	 */
	@Override
	public Object plugin(Object target) {
		return Plugin.wrap(target, this);
	}


	/**
	 * 数据权限 处理 SQL追加
	 * 
	 * @param handler
	 */
	public void handler(StatementHandler handler) {
		BoundSql boundSql = handler.getBoundSql();
		String sql = boundSql.getSql();
		DataRowAuthModel authorityData = getLocalAuthorityData();
		if (authorityData == null) {
			return;
		}
		Set<DataRowAuthColumn> columns = authorityData.getFilterColumns();
		if (CollectionUtils.isEmpty(columns)) {
			return;
		}
		for (DataRowAuthColumn column : columns) {
			RowDataHandlerType sqlHandler = column.getType();
			// 处理SQL 追加权限
			sql = sqlHandler.handlerSql(sql, column.getColumn());
		}
		overrideSql(boundSql, sql);
	}

	@Override
	public void setProperties(Properties properties) {
		String dialect = properties.getProperty("dialect");
        LOGGER.info("RowDataHelper for mybatis intercept dialect:{}", dialect);
	}
}
